<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>object oriented</title>
    <style type="text/css">
pre{
    /*font-family: "微软雅黑";*/
    font-size: 16px;
    line-height: 26px;
}
#div1 input{
    background-color: #fff;
}
#div1 input.active{
    background-color: yellow;
}
#div1 div{
    width: 200px;
    height: 200px;
    background-color: #ccc;
    display: none;
}

#div2{
    width: 100px;
    height: 100px;
    position: absolute;
    bottom:0;
    right:0;
    background-color: #CCCCFF;
}
#div3{
    width: 100px;
    height: 100px;
    position: absolute;
    bottom:0;
    right:200px;
    background-color: #99CCFF;
}

    </style>
</head>
<body>

<pre>
实例：面相对象的选项卡

把面向过程的程序，改写成面向对象的形式
原则：
    不能有函数嵌套，但可以有全局变量
过程：
    onload(初始化整个程序)        构造函数(初始化整个对象)
    全局变量                      属性
    函数                          方法
改错：
    this、事件、闭包、传参



</pre>

<div id="div1">
    <input class="active" type="button" value="aaa"/>
    <input type="button" value="bbb"/>
    <input type="button" value="ccc"/>
    <div style="display:block;">aaaaaaaaaaa</div>
    <div>bbbbbbbbbbb</div>
    <div>ccccccccccc</div>
</div>

<div id="div2">随便拖拽</div>
<div id="div3">限制拖拽</div>


<script>

// 1、面向过程的写法----------------------------------------------------------------------------
/*window.onload = function(){
    var oDiv = document.getElementById("div1");
    var aBtn = oDiv.getElementsByTagName("input");
    var aDiv = oDiv.getElementsByTagName("div");

    for(var i=0; i<aBtn.length; i++){

        aBtn[i].index = i;
        aBtn[i].onclick = function(){
            for(var i=0; i<aBtn.length; i++){
                aBtn[i].className = "";
                aDiv[i].style.display = "none";
            }
            this.className = "active";
            aDiv[this.index].style.display = "block";
        }
    }
}*/


// 改写成面向对象----------------------------------------------------------------------------
// 1、函数不能有嵌套，先拎出来
// 拎出来后，点击btn，报错，说fnClick里的aBtn未定义，所以还要把aBtn,aDiv也拎出来，作为全局变量

/*var aBtn = null;
var aDiv = null;
window.onload = function(){
    var oDiv = document.getElementById("div1");
    aBtn = oDiv.getElementsByTagName("input");
    aDiv = oDiv.getElementsByTagName("div");

    for(var i=0; i<aBtn.length; i++){

        aBtn[i].index = i;
        aBtn[i].onclick = fnClick;
    }
}

function fnClick(){
    for(var i=0; i<aBtn.length; i++){
        aBtn[i].className = "";
        aDiv[i].style.display = "none";
    }
    this.className = "active";
    aDiv[this.index].style.display = "block";
}*/






// 2、window.onload --> 构造函数----------------------------------------------------------------------------
// 变量 --> 属性
// 函数 --> 方法


/*window.onload = function(){
    new TabSwitch("div1");
}

function TabSwitch(id){
    var oDiv = document.getElementById(id);
    this.aBtn = oDiv.getElementsByTagName("input");
    this.aDiv = oDiv.getElementsByTagName("div");

    for(var i=0; i<this.aBtn.length; i++){

        this.aBtn[i].index = i;
        // fnClick前面要加this,不然报错：fnClick is not defined 
        this.aBtn[i].onclick = this.fnClick;
    }
}

TabSwitch.prototype.fnClick = function(){
    // 这里的this是TabSwitch的方法，应该指向new出来的TabSwitch("div1")这个对象
    // 但是这里却指向了被点击的btn
    // 原因是：this.aBtn[i].onclick = this.fnClick; 把fnClick赋值给了aBtn[i]的click事件，所以导致了fnClick里的this指向的aBtn[i]
    console.log(this); 

    // 所以这里会报错：Cannot read property 'length' of undefined
    for(var i=0; i<this.aBtn.length; i++){
        this.aBtn[i].className = "";
        this.aDiv[i].style.display = "none";
    }

    this.className = "active";
    this.aDiv[this.index].style.display = "block";
}*/





// 3、改错----------------------------------------------------------------------------

window.onload = function(){
    new TabSwitch("div1");
}

function TabSwitch(id){
    var _this = this;
    var oDiv = document.getElementById(id);
    this.aBtn = oDiv.getElementsByTagName("input");
    this.aDiv = oDiv.getElementsByTagName("div");

    for(var i=0; i<this.aBtn.length; i++){

        this.aBtn[i].index = i;

        this.aBtn[i].onclick = function(){
            // 这样调用就没有把this.fnClick()转移到this.aBtn[i]的click上去
            // this.fnClick();的写法，报错：undefined is not a function
            // 原因是，这里的this依然是指this.aBtn[i]按钮
            // this.fnClick();
            _this.fnClick(this);
        }
    }
}

TabSwitch.prototype.fnClick = function(oBtn){

    for(var i=0; i<this.aBtn.length; i++){
        this.aBtn[i].className = "";
        this.aDiv[i].style.display = "none";
    }
    // 在面向过程中，this是指当前点击的按钮，而这里的this指向的是div1对象
    // 所以这里是通过传参的形式把当前btn传进来
    oBtn.className = "active";
    this.aDiv[oBtn.index].style.display = "block";
}




//---继承应用：拖拽------------------------------------------------------------------------

// 面相过程
/*window.onload = function(){
    var oDiv = document.getElementById("div2");
    var disX = 0;
    var disY = 0;
    oDiv.onmousedown = function(e){
        var oEvent = e || event;

        disX = oEvent.clientX - oDiv.offsetLeft;
        disY = oEvent.clientY - oDiv.offsetTop;
        console.log(disX, disY);

        document.onmousemove = function(e){
            var oEvent = e || event;
            var left = oEvent.clientX - disX;
            var top = oEvent.clientY - disY;
            oDiv.style.left = left + 'px';
            oDiv.style.top = top + 'px';
        }

        document.onmouseup = function(){
            document.onmouseup = null;
            document.onmousemove = null;
        }
        return false;
    }
}*/



// 面相对象-----------------------------------------------
// 1、把嵌套的函数拎出来; 一些公用的变量，暂时先放到全局变量
/*var oDiv = null;

window.onload = function(){
    oDiv = document.getElementById("div2");
    var disX = 0;
    var disY = 0;
    oDiv.onmousedown = fnDown;
}

function fnDown(e){
    var oEvent = e || event;
    disX = oEvent.clientX - oDiv.offsetLeft;
    disY = oEvent.clientY - oDiv.offsetTop;
    console.log(disX, disY);

    document.onmousemove = fnMove;
    document.onmouseup = fnUp;
    return false;
}

function fnMove(e){
    var oEvent = e || event;
    var left = oEvent.clientX - disX;
    var top = oEvent.clientY - disY;
    oDiv.style.left = left + 'px';
    oDiv.style.top = top + 'px';
}

function fnUp(){
    document.onmouseup = null;
    document.onmousemove = null;
}*/



// 2、window.onload --> 构造函数----------------------------------------------------------------------------
// 变量 --> 属性
// 函数 --> 方法

window.onload = function(){
    new Drag("div2");
}
function Drag(id){
    var _this = this;
    this.oDiv = document.getElementById(id);
    var disX = 0;
    var disY = 0;
    this.oDiv.onmousedown = function(e){
        _this.fnDown(e);
    }
}

Drag.prototype.fnDown = function(e){
    var _this = this;
    var oEvent = e || event;
    disX = oEvent.clientX - this.oDiv.offsetLeft;
    disY = oEvent.clientY - this.oDiv.offsetTop;
    console.log(disX, disY);

    document.onmousemove = function(e){
        _this.fnMove(e);
    }
    document.onmouseup = function(){
        _this.fnUp();  
    } 
    return false;
}

Drag.prototype.fnMove = function(e){
    var oEvent = e || event;
    var left = oEvent.clientX - disX;
    var top = oEvent.clientY - disY;
    this.oDiv.style.left = left + 'px';
    this.oDiv.style.top = top + 'px';
}

Drag.prototype.fnUp = function(){
    document.onmouseup = null;
    document.onmousemove = null;
}


// 3、使用继承--------------------------------------------------
window.onload = function(){
    new LimitDrag("div3");
}
function LimitDrag(id){
    Drag.call(this, id);
}
for(var i in Drag.prototype){
    LimitDrag.prototype[i] = Drag.prototype[i];
}


LimitDrag.prototype.fnMove = function(e){
    var oEvent = e || event;
    var left = oEvent.clientX - disX;
    var top = oEvent.clientY - disY;
     //左边出不去
    if(left < 0){  
        left = 0;
    }
    //右边出不去
    else if(left >　document.documentElement.clientWidth - this.oDiv.offsetWidth){
        left =　document.documentElement.clientWidth - this.oDiv.offsetWidth;
    }
    //上边出不去
    if(top < 0){  
        top = 0;
    }
    //下边出不去
    else if(top > document.documentElement.clientHeight - this.oDiv.offsetHeight){
        top = document.documentElement.clientHeight - this.oDiv.offsetHeight;
    }
    this.oDiv.style.left = left + 'px';
    this.oDiv.style.top = top + 'px';
}




</script>
</body>
</html>